package com.naton.mydemo.model.dao

import android.util.Log
import androidx.room.*
import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery
import java.lang.reflect.ParameterizedType

abstract class BaseDao<T> {
    /**
     * 插入一条
     *
     * 当DAO里面的某个方法添加了@Insert注解 Room会生成一个实现  将所有参数插入到数据库中的单个事务
     *
     * onConflict: 表示当插入有冲突的时候处理策略 OnConflictStrategy封装了Room解决冲突的相关策略
     *
     * OnConflictStrategy.REPLACE: 冲突策略是取代旧数据同时继续事务
     * OnConflictStrategy.ROLLBACK: 冲突策略是回滚事务
     * OnConflictStrategy.ABORT: 冲突策略是终止事务，默认策略
     * OnConflictStrategy.FAIL: 冲突策略是事务失败
     * OnConflictStrategy.IGNORE: 冲突策略是忽略冲突
     *
     * @param t
     */
    /**
     * 插入一个
     * @param t
     * @return
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insert(t: T)

    /**
     * 插入多个
     * @param ts
     * @return
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insert(vararg ts: T)

    /**
     * 插入一个集合
     * @param ts
     * @return
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insert(ts: List<T>?)

    /**
     * 更新  根据参数对象的主键更新指定的row的数据
     * @param t
     * @return
     */
    @Update(onConflict = OnConflictStrategy.REPLACE)
    abstract fun update(t: T): Int

    /**
     * 删除单个  根据主键删除指定row
     */
    @Delete
    abstract fun delete(t: T): Int

    /**
     * 删除全部
     * @return
     */
    fun deleteAll(): Int {
        val query = SimpleSQLiteQuery("delete from $tableName")
        return doDeleteAll(query)
    }

    /**
     * 查询全部
     * @return
     */
    fun findAll(): List<T> {
        val query = SimpleSQLiteQuery("select * from $tableName")
        return doFindAll(query)
    }

    @RawQuery
    abstract fun doDeleteAll(query: SupportSQLiteQuery?): Int
    @RawQuery
    abstract fun doFindAll(query: SupportSQLiteQuery?): List<T>

    /**
     * 获取表名
     */
    val tableName: String
        get() {
            val clazz = (javaClass.superclass.genericSuperclass as ParameterizedType)
                .actualTypeArguments[0] as Class<*>
            val tableName = clazz.simpleName
            Log.d("ez", "getTableName: -->$tableName")
            return tableName
        }
}